package com.zw.a.basic.a12.demo05_exercise;

import java.io.*;

//案例: 演示字节流拷贝文件的效率.
/*
    读写速度从高到底分别是:
        1. 高效流一次读写一个字节数组.         71毫秒
        2. 普通流一次读写一个字节数组.         70毫秒              掌握
        3. 高效流一次读写一个字节.             609毫秒             掌握
        4. 普通流一次读写一个字节.             138550毫秒
    小细节:
        因为字节缓冲流提供的缓冲区的大小是: 8196个字节(8KB), 所以如果我们用 普通流一次读写一个字节数组的方式拷贝文件,
        且自定义的数组长度在 8196个字节, 那么可能会出现: 普通流一次读写一个字节数组的速度 > 高效流一次读写一个字节数组的速度
 */
public class Demo03 {
    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        //1.分别通过四种方式拷贝视频文件, 并观察它们的效率.
        //2.通过普通的字节流一次读写一个字节的形式实现.
        //method01();                   138550毫秒

        //3.通过普通的字节流一次读写一个字节数组的形式实现.
        //method02();                     //70毫秒

        //4.通过高效的字节流一次读写一个字节的形式实现.
        //method03();                      //609毫秒

        //5.通过高效的字节流一次读写一个字节数组的形式实现.
        //method04();                     71毫秒


        long end = System.currentTimeMillis();
        System.out.println("拷贝时间为: " + (end - start));
    }

    public static void method04() throws IOException {
        //1. 创建输入流对象, 关联数据源文件.
        BufferedInputStream bis = new BufferedInputStream( new FileInputStream("day12/data/1.avi"));
        //2. 创建输出流对象, 关联目的地文件.
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day12/data/5.avi"));
        //3. 定义变量, 记录读取到的内容或者有效字节(符)数.
        int len = 0;
        byte[] bys = new byte[8196];
        //4. 循环读取,只要条件满足就一直读, 并将读取到的内容赋值给变量.
        while ((len = bis.read(bys)) != -1) {
            //5. 将读取到的内容写入到目的地文件中.
            bos.write(bys, 0, len);
        }
        //6. 关流, 释放资源.
        bis.close();
        bos.close();
    }

    public static void method03() throws IOException {
        //1. 创建输入流对象, 关联数据源文件.
        FileInputStream fis = new FileInputStream("day12/data/1.avi");
        BufferedInputStream bis = new BufferedInputStream(fis);
        //2. 创建输出流对象, 关联目的地文件.
        FileOutputStream fos = new FileOutputStream("day12/data/4.avi");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //3. 定义变量, 记录读取到的内容或者有效字节(符)数.
        int len = 0;
        //4. 循环读取,只要条件满足就一直读, 并将读取到的内容赋值给变量.
        while ((len = bis.read()) != -1) {
            //5. 将读取到的内容写入到目的地文件中.
            bos.write(len);
        }
        //6. 关流, 释放资源.
        bis.close();
        bos.close();
    }

    public static void method02() throws IOException {
        //1. 创建输入流对象, 关联数据源文件.
        FileInputStream fis = new FileInputStream("day12/data/1.avi");
        //2. 创建输出流对象, 关联目的地文件.
        FileOutputStream fos = new FileOutputStream("day12/data/3.avi");
        //3. 定义变量, 记录读取到的内容或者有效字节(符)数.
        int len = 0;
        byte[] bys = new byte[8196];
        //4. 循环读取,只要条件满足就一直读, 并将读取到的内容赋值给变量.
        while ((len = fis.read(bys)) != -1) {
            //5. 将读取到的内容写入到目的地文件中.
            fos.write(bys, 0, len);
        }
        //6. 关流, 释放资源.
        fis.close();
        fos.close();
    }

    public static void method01() throws IOException {
        //1. 创建输入流对象, 关联数据源文件.
        FileInputStream fis = new FileInputStream("day12/data/1.avi");
        //2. 创建输出流对象, 关联目的地文件.
        FileOutputStream fos = new FileOutputStream("day12/data/2.avi");
        //3. 定义变量, 记录读取到的内容或者有效字节(符)数.
        int len = 0;
        //4. 循环读取,只要条件满足就一直读, 并将读取到的内容赋值给变量.
        while ((len = fis.read()) != -1) {
            //5. 将读取到的内容写入到目的地文件中.
            fos.write(len);
        }
        //6. 关流, 释放资源.
        fis.close();
        fos.close();
    }
}
